﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Nsf.Samples.RetryActivitySample.Infrastructure.Common.Commands;
using Nsf.Samples.RetryActivitySample.Infrastructure.Common.FaultDetails;

namespace Nsf.Samples.RetryActivitySample.ServiceContract
{
    [ServiceContract]
    public interface IWorkflowManager
    {
        /// <summary>
        /// Запуск нового рабочего потока
        /// </summary>
        /// <param name="workflowType">Название типа рабочего потока</param>
        /// <returns>Идентификатор созданного рабочего потока</returns>
        [OperationContract]
        [FaultContract(typeof(ValidationFaultDetails))]
        [FaultContract(typeof(ProcessingFaultDetails))]
        Guid StartWorkflow(String workflowType);

        /// <summary>
        /// Запрос рабочего потока, во время выполнения которого произошла ошибка, но есть возможность повторить попытку
        /// </summary>
        /// <param name="workflowInstanceId">Идентификатор рабочего потока</param>
        [OperationContract]
        [FaultContract(typeof(ValidationFaultDetails))]
        [FaultContract(typeof(ProcessingFaultDetails))]
        RetryableWorkflowInfo GetRetryableWorkflow(Guid workflowInstanceId);

        /// <summary>
        /// Запрос перечня рабочих потоков, во время выполнения которых произошла ошибка, но есть возможность повторной попытку
        /// </summary>
        /// <param name="workflowType">Тип рабочих потоков. null интерпретируется как все типы</param>
        [OperationContract]
        [FaultContract(typeof(ValidationFaultDetails))]
        [FaultContract(typeof(ProcessingFaultDetails))]
        List<RetryableWorkflowInfo> GetRetryableWorkflows(String workflowType);

        /// <summary>
        /// Повторое выполнение действия, в котором произошла ошибка
        /// </summary>
        /// <param name="retryableActivityInfo">Информация о повторно выполняемом действии</param>
        [OperationContract]
        [FaultContract(typeof(ValidationFaultDetails))]
        [FaultContract(typeof(ProcessingFaultDetails))]
        void RetryActivity(RetryableActivityInfo retryableActivityInfo);

        /// <summary>
        /// Повторное выполнение всех действий рабочего потока, в которых произошла ошибка
        /// </summary>
        /// <param name="retryableWorkflowInfo">Информация о повторно выполняемых действиях</param>
        [OperationContract]
        [FaultContract(typeof(ValidationFaultDetails))]
        [FaultContract(typeof(ProcessingFaultDetails))]
        void RetryWorkflow(RetryableWorkflowInfo retryableWorkflowInfo);

        /// <summary>
        /// Отправка рабочему потоку команды
        /// </summary>
        /// <param name="workflowInstanceId">Идентификатор рабочего потока, которому отправляется команда</param>
        /// <param name="commandData">Информация о команде</param>
        [OperationContract]
        [FaultContract(typeof(ValidationFaultDetails))]
        [FaultContract(typeof(ProcessingFaultDetails))]
        void SendCommandToWorkflow(Guid workflowInstanceId, CommandData commandData);

    }

    /// <summary>
    /// Информация о действиях рабочего потока, выполнение которых можно повторить
    /// </summary>
    [DataContract]
    public class RetryableWorkflowInfo
    {
        /// <summary>
        /// Идентификатор рабочего потока
        /// </summary>
        [DataMember]
        public Guid WorkflowInstanceId { get; set; }
        /// <summary>
        /// Тип рабочего потока
        /// </summary>
        [DataMember]
        public String WorkflowType { get; set; }
        /// <summary>
        /// Список повторяемых действий
        /// </summary>
        [DataMember]
        public List<RetryableActivityInfo> RetryableActivities { get; set; }
    }

    /// <summary>
    /// Информация о действии, в котором произошла ошибка, но которое можно повторить
    /// </summary>
    [DataContract]
    public class RetryableActivityInfo
    {
        /// <summary>
        /// Имя действия
        /// </summary>
        [DataMember]
        public String ActivityName { get; set; }
        /// <summary>
        /// Описание действия
        /// </summary>
        [DataMember]
        public String ActivityDescription { get; set; }
        /// <summary>
        /// Информация об ошибке
        /// </summary>
        [DataMember]
        public String ErrorMessage { get; set; }
        /// <summary>
        /// Имя очереди
        /// </summary>
        [DataMember]
        public Guid QueueName { get; set; }
        /// <summary>
        /// Идентификатор рабочего потока
        /// </summary>
        [DataMember]
        public Guid WorkflowInstanceId { get; set; }
    }
}
